#pragma once
#include<iostream>
#include <pthread.h>
#include<string>
#include<functional>

class thread
{
private:
    typedef enum{
        NEW = 0,
        RUN,
        EXIT
    }ThreadStatus_t;
    using ThreadFunc_t = std::function<void(void*)>;
public:
    thread(int num, ThreadFunc_t func , void* arg = nullptr)
        :_func(func)
        ,_arg(arg)
        ,_status(NEW)
    {
        _name = "thread" + std::to_string(num);
    }
    void run()
    {
        int ret = pthread_create(&_tid, nullptr, runHelper, this);
        if(ret != 0)
        {
            std::cout << "pthread_create error" << std::endl;
            return;
        }
        _status = RUN;
    }
    void join()
    {
        if(_status != EXIT)
        {
            int ret =pthread_join(_tid, nullptr);
            if(ret != 0)
            {
                std::cout << "pthread_join error" << std::endl;
                return;
            }
            _status = EXIT;
        }
    }

    pthread_t threadId()
    {
        return _tid;
    }

    const std::string& threadName()
    {
        return _name;
    }

    ThreadStatus_t threadStatus()
    {
        return _status;
    }

    ~thread()
    {}

private:
    static void* runHelper(void* arg)
    {
        thread* p = static_cast<thread*>(arg);
        (*p)();
        return nullptr;
    }
    void operator()()
    {
        if(_func != nullptr)
        {
            _func(_arg);
        }
    }

private:
    pthread_t _tid; // 线程id
    void* _arg; // 线程参数
    ThreadFunc_t _func;// 线程入口函数
    ThreadStatus_t _status; // 线程状态
    std::string _name; // 线程名称
};